package order

import (
	"context"
	"errors"
	"strconv"
	v1 "video-api/api/v1"
	"video-api/internal/consts"
	"video-api/internal/middleware"
	"video-api/internal/model/input"
	"video-api/internal/model/out"
	"video-api/internal/service"
	"video-api/utility"
	"video-api/utility/cdn_url"
	"video-api/utility/metrics"

	"github.com/gogf/gf/errors/gerror"
	"github.com/gogf/gf/v2/frame/g"
)

type OrderController struct{}

var OrderHandle = new(OrderController)

func (s *OrderController) GetOrderList(ctx context.Context, param *v1.OrderInfoReq) (*out.Paging, error) {
	g.Log().Info(ctx, "OrderController->GetOrderList-param: ", g.Map{"param": param})
	userInfo := middleware.GetUserInfo(ctx)
	if userInfo == nil || userInfo.UserId == 0 {
		return nil, gerror.New("user not exist")
	}
	orderParam := &input.OrderList{
		Page:     param.Page,
		PageSize: param.PageSize,
		UserId:   int(userInfo.UserId),
		Status:   consts.PAY_COMPLETED,
	}
	// 获取订单信息
	list, count, err := service.OrderService().GetOrderList(ctx, orderParam)
	if err != nil {
		g.Log().Error(ctx, "GetOrderList->GetOrderList: err", err)
		return nil, err
	}
	goodsIds := make([]int64, 0)
	orders := make([]*v1.OrderInfoRes, len(list))
	goodsInfoMap := make(map[int64]*out.Goods)
	for i, v := range list {
		if orders[i] == nil {
			orders[i] = new(v1.OrderInfoRes)
		}
		orders[i].DTO(ctx, v)
		goodsIds = append(goodsIds, v.GoodsId)
	}
	// 获取商品信息
	goodsIds = utility.DeDuplicateSlice(goodsIds)
	goodsInfos := make([]*out.Goods, 0)
	if len(goodsIds) > 0 {
		goodsInfos, err = service.GoodsService().GetGoodsInfoByParam(ctx, &input.GoodsDetail{
			GoodsIds: goodsIds,
		})
	}
	// 商品信息
	for i, v := range goodsInfos {
		goodsInfoMap[v.Id] = goodsInfos[i]
	}

	for i, _ := range orders {
		if goodsInfoMap[orders[i].GoodsId] != nil {
			// 商品信息
			orders[i].Coins = goodsInfoMap[orders[i].GoodsId].Coins
			orders[i].Name = goodsInfoMap[orders[i].GoodsId].Name
			orders[i].Bonus = goodsInfoMap[orders[i].GoodsId].Bonus
			orders[i].GoodsType = goodsInfoMap[orders[i].GoodsId].GoodsType
		}
	}
	return out.FillPaging(count, param.Page, param.PageSize, orders), nil
}

// GetUnlockShortDramas 获取消费列表
func (s *OrderController) GetUnlockShortDramas(ctx context.Context, param *v1.UnlockDramasReq) (*out.Paging, error) {
	g.Log().Info(ctx, "OrderController->GetUnlockShortDramas-param: ", g.Map{"param": param})
	userInfo := middleware.GetUserInfo(ctx)
	if userInfo == nil || userInfo.UserId == 0 {
		return nil, gerror.New("user not exist")
	}
	list, count, err := service.OrderService().GetUnlockShortDramaList(ctx, &input.UnlockDramaList{
		Page:     param.Page,
		PageSize: param.PageSize,
		UserId:   int(userInfo.UserId),
	})
	if err != nil {
		g.Log().Error(ctx, "OrderController->GetUnlockShortDramas->GetUnlockShortDramaList: err", err, g.Map{"user_id": userInfo.UserId})
		return nil, err
	}

	// 获取短剧信息
	shortDramaIds := make([]int64, 0)
	shortDramaEpisodesMap := make(map[int64]*out.ShortDramaEpisodesDetail)
	for _, v := range list {
		shortDramaIds = append(shortDramaIds, v.ShortDramaId)
	}
	// 去重
	shortDramaIds = utility.DeDuplicateSlice(shortDramaIds)
	shortDramaEpisodesDetails := make([]*out.ShortDramaEpisodesDetail, 0)
	shortDramaTagMap := make(map[int64][]string)
	if len(shortDramaIds) > 0 {
		// 获取短剧详情
		shortDramaEpisodesDetails, err = service.ShortDramaService().GetShortDramaEpisodes(ctx, &input.ShortDramaEpisodes{
			Ids: shortDramaIds,
		})
		if err != nil {
			g.Log().Error(ctx, "OrderController->GetUnlockShortDramas->GetShortDramaEpisodes: err", err, g.Map{"user_id": userInfo.UserId})
			return nil, err
		}
		// 获取短剧标签
		shortDramaTags := make([]*out.ShortDramaTags, 0)
		shortDramaTags, err = service.ContentService().GetShortDramaTagsList(ctx, &input.ShortDramaTagList{ShortDramaIds: shortDramaIds})
		if err != nil {
			g.Log().Error(ctx, "OrderController->GetUnlockShortDramas->GetShortDramaTagsList: err", err, g.Map{"user_id": userInfo.UserId})
			return nil, err
		}
		for _, tag := range shortDramaTags {
			if shortDramaTagMap[tag.ShortDramaId] == nil {
				shortDramaTagMap[tag.ShortDramaId] = make([]string, 0)
			}
			shortDramaTagMap[tag.ShortDramaId] = append(shortDramaTagMap[tag.ShortDramaId], tag.TagName)
		}

	}
	for i, v := range shortDramaEpisodesDetails {
		shortDramaEpisodesMap[v.Id] = shortDramaEpisodesDetails[i]
	}
	respDate := make([]*v1.UnlockDramaResp, len(list))
	for i, _ := range list {
		ele := new(v1.UnlockDramaResp)
		ele.DTO(ctx, shortDramaEpisodesMap[list[i].ShortDramaEpisodeId])
		ele.UnlockType = list[i].UnlockType
		ele.Coins = list[i].Coins
		ele.Tags = shortDramaTagMap[list[i].ShortDramaId]
		respDate[i] = ele
	}
	return out.FillPaging(count, param.Page, param.PageSize, respDate), nil
}

// UnlockShortDrama 解锁短剧
func (s *OrderController) UnlockShortDrama(ctx context.Context, param *v1.UnlockDramaReq) (*out.ShortDramaEpisodesEntity, error) {
	g.Log().Info(ctx, "OrderController->UnlockShortDrama-param: ", g.Map{"param": param})
	userInfo := middleware.GetUserInfo(ctx)
	if userInfo == nil {
		return nil, gerror.New("user not exist")
	}
	//TODO userid登录获取
	metrics.HttpUnlockShortDramaCounts.WithLabelValues(strconv.FormatInt(userInfo.UserId, 10), strconv.Itoa(int(param.ShortDramaId))).Inc() //统计解锁短剧次数
	episode, err := service.OrderService().UnlockShortDrama(ctx, &input.UnlockDrama{
		UserId:       userInfo.UserId,
		Coins:        param.Coins,
		EpisodeId:    param.EpisodeId,
		ShortDramaId: param.ShortDramaId,
	})
	if err != nil {
		g.Log().Error(ctx, "OrderController->UnlockShortDrama: err", err)
		return nil, errors.New(err.Error())
	}
	//resp := &v1.UnlockDramaResp{
	//	ShortDramaId: param.ShortDramaId,
	//	EpisodeId:    param.EpisodeId,
	//}
	if episode != nil {
		prefix := g.Cfg().MustGet(ctx, "cdnurl.url").String()
		urlInfo, _ := cdn_url.CdnUrl(prefix, episode.VideoUrl)
		episode.VideoUrl = urlInfo.Url
		episode.VideoUrlTime = urlInfo.Timestamp
	}
	return episode, nil
}

// OrderCreate 创建订单
func (s *OrderController) OrderCreate(ctx context.Context, req *v1.OrderCreateReq) (res *v1.OrderCreateRes, err error) {
	allowed, err := utility.IsRequestAllowed(ctx, 1, req)
	if err != nil {
		return nil, err
	}
	if !allowed {
		return nil, gerror.New("request too fast.")
	}
	create, err := service.OrderService().OrderCreate(ctx, &req.OrderCreate)
	if err != nil {
		return nil, err
	}
	res = new(v1.OrderCreateRes)
	res.OrderEntity = create
	return res, nil
}

func (s *OrderController) OrderPay(ctx context.Context, req *v1.OrderPayReq) (res *v1.OrderPayRes, err error) {
	allowed, err := utility.IsRequestAllowed(ctx, 1, req)
	if err != nil {
		return nil, err
	}
	if !allowed {
		return nil, gerror.New("request too fast.")
	}
	pay, err := service.OrderService().OrderPay(ctx, &req.OrderPay)
	if err != nil {
		return nil, err
	}
	res = new(v1.OrderPayRes)
	res.OrderEntity = pay
	return res, err
}
